Micron Document
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| SparkN0de-git | SparkN0de |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Displaying Raw • View renderedDownload


README.md dev (af76f09d) Text, 27.41 KB

Tc9d1d9# Reticulum MeshChatX

[Tff7b72Русский](Te6edf3lang/README.ru.md) | [Tff7b72Deutsch](Te6edf3lang/README.de.md) | [Tff7b72Italiano](Te6edf3lang/README.it.md) | [Tff7b72中文](Te6edf3lang/README.zh.md) | [Tff7b72日本語](Te6edf3lang/README.ja.md)

Fork of [Tff7b72Reticulum MeshChat](Te6edf3https://github.com/liamcottle/reticulum-meshchat) by Liam Cottle. MeshChatX adds LXST voice calls, RRC relay chat, Nomad map overlays, plugins, raw SQLite (no Peewee), and Electron 41 desktop builds.

This project is independent from the original Reticulum MeshChat project and is not affiliated with it.

Tff7b72- Website: [Tff7b72meshchatx.com](Te6edf3https://meshchatx.com)
Tff7b72- Source: [Tff7b72github.com/Quad4-Software/MeshChatX](Te6edf3https://github.com/Quad4-Software/MeshChatX)
Tff7b72- Mirror: [Tff7b72lavaforge.org/Reticulum-Things/MeshChatX](Te6edf3https://lavaforge.org/Reticulum-Things/MeshChatX)
Tff7b72- Releases: [Tff7b72github.com/Quad4-Software/MeshChatX](Te6edf3https://github.com/Quad4-Software/MeshChatX)
Tff7b72- Changelog: [Ta5d6ff`CHANGELOG.md`](CHANGELOG.md)
Tff7b72- Donate: [Ta5d6ff`donate.md`](donate.md) ([Donation](#donation))
Tff7b72- LXMF: Ta5d6ff`f489752fbef161c64d65e385a4e9fc74`
Tff7b72- Umbrel App Store: [Tff7b72apps.umbrel.com/app/meshchatx](Te6edf3https://apps.umbrel.com/app/meshchatx)

<a href="https://apps.obtainium.imranr.dev/redirect.html?r=obtainium://add/https://github.com/Quad4-Software/MeshChatX"><img src="https://raw.githubusercontent.com/ImranR98/Obtainium/main/assets/graphics/badge_obtainium.png" height="60" alt="Get it on Obtainium"></a>

rngit NomadNet Node: Ta5d6ff`132f67e79d9b24aad014e93015fb858f:/page/index.mu`

rngit: Ta5d6ff`git clone rns://06a54b505bb67b25ef3f8097e8001edc/public/MeshChatX`

Tc9d1d9## Important Changes from Reticulum MeshChat

Tff7b72- Uses LXST for calls
Tff7b72- Integrates [Tff7b72RRC](Te6edf3https://rrc.kc1awv.net/0)
Tff7b72- Expanded tools
Tff7b72- Map w/ MBTiles support, remote KMZ/KML/GeoJSON overlays (NomadNet Ta5d6ff`/file/` and RNGit sparse fetch)
Tff7b72- Panes and Tabs
Tff7b72- Replaced Peewee ORM with raw SQL.
Tff7b72- Replaced Axios with native fetch.
Tff7b72- Uses Electron 41.x (bundled Node 24 runtime).
Tff7b72- .whls ships with webserver and built-in frontend assets for more deployment options.
Tff7b72- i18n
Tff7b72- PNPM and UV for dependency management.

Tc9d1d9## Requirements

Tff7b72- Python Ta5d6ff`>=3.11` (from Ta5d6ff`pyproject.toml`)
Tff7b72- Node.js Ta5d6ff`>=24` (from Ta5d6ff`package.json` Ta5d6ff`engines`)
Tff7b72- pnpm Ta5d6ff`11.1.2` (from Ta5d6ff`package.json` Ta5d6ff`packageManager`)
Tff7b72- UV (used by Ta5d6ff`Taskfile.yml` and CI workflows)

**Browser Versions Required:**

Safari 16.4 or later, Chrome 111 or later, Firefox 128 or later (bundled web UI).

Ta5d6ff```Ta5d6ffbash
task install
task format
task lint
task Tffa657test
task build
Ta5d6ff```

Tc9d1d9## Install Methods

Use the method that matches your environment and packaging preference.

| Method | Includes frontend assets | Architectures | Best for |
| ----------------------- | ------------------------ | ------------------------------------------ | ---------------------------------------------- |
| Docker image | Yes | Ta5d6ff`linux/amd64`, Ta5d6ff`linux/arm64` | Fastest setup on Linux servers/hosts |
| Python wheel (Ta5d6ff`.whl`) | Yes | Any Python-supported architecture | Headless/web-server install without Node build |
| Linux AppImage | Yes | Ta5d6ff`x64`, Ta5d6ff`arm64` | Portable desktop use |
| Debian package (Ta5d6ff`.deb`) | Yes | Ta5d6ff`x64`, Ta5d6ff`arm64` | Debian/Ubuntu installs |
| RPM package (Ta5d6ff`.rpm`) | Yes | CI-runner dependent for published artifact | Fedora/RHEL/openSUSE style systems |
| From source | Built locally | Host architecture | Development and custom builds |

Notes:

Tff7b72- GitHub Actions builds tagged releases (Linux wheel/AppImage/deb/rpm, Windows, macOS, Flatpak, Android APKs when the tag is on Ta5d6ff`dev` or Ta5d6ff`master`, SLSA, draft release) in one run via Ta5d6ff`.github/workflows/build-release.yml`; the container image via Ta5d6ff`.github/workflows/docker.yml`. Branch and PR Android CI stays in Ta5d6ff`.github/workflows/android-build.yml`.
Tff7b72- Linux Ta5d6ff`x64` and Ta5d6ff`arm64` AppImage + DEB are built on GitHub; RPM is attempted and uploaded when produced.

Tc9d1d9## Docker

Tff7b72- **Docker Hub:** Ta5d6ff`quad4io/meshchatx`
Tff7b72- **GHCR:** Ta5d6ff`ghcr.io/quad4-software/meshchatx`
Tff7b72- **Variants:** default tags (for example Ta5d6ff`:latest`) are the standard Alpine image. Use Ta5d6ff`-hardened` for the Chainguard/Wolfi image, or Ta5d6ff`-extra` for Alpine plus **i2pd** and **yggdrasil** (for example Ta5d6ff`:latest-extra`, built from the same Ta5d6ff`Dockerfile` with Ta5d6ff`VARIANT=extra`).

Ta5d6ff```Ta5d6ffbash
docker compose up -d
Ta5d6ff```

Ta5d6ff```Ta5d6ffbash
docker run -d --name reticulum-meshchatx Tffea00\
--restart unless-stopped Tffea00\
--init Tffea00\
--user T79c0ff1000:1000 Tffea00\
--security-opt no-new-privileges:true Tffea00\
--cap-drop ALL Tffea00\
--read-only Tffea00\
--tmpfs /tmp:noexec,nosuid,sizeTff7b72=256m Tffea00\
--tmpfs /home/meshchat:nosuid,sizeTff7b72=64m Tffea00\
--cpusTff7b72=T79c0ff2.0 Tffea00\
--memoryTff7b72=1g Tffea00\
--memory-reservationTff7b72=256m Tffea00\
--pids-limitTff7b72=T79c0ff512 Tffea00\
-p T79c0ff127.0.0.1:8000:8000 Tffea00\
-v meshchatx-config:/config Tffea00\
ghcr.io/quad4-software/meshchatx:latest
Ta5d6ff```

You can substitute Ta5d6ff`quad4io/meshchatx:latest` for the image if you prefer Docker Hub.

Default compose file maps:

Tff7b72- Ta5d6ff`127.0.0.1:8000` on host -> container port Ta5d6ff`8000`
Tff7b72- Docker **named volume** Ta5d6ff`meshchatx-config` -> Ta5d6ff`/config` for persistence (works with the image Ta5d6ff`meshchat` user, UID 1000, without bind-mount permission fixes)

**Optional: bind mount a host directory instead**

If you want data under a host path (for example Ta5d6ff`./meshchat-config`), replace the volume line with Ta5d6ff`-v "$(pwd)/meshchat-config:/config"` (Compose: change the service Ta5d6ff`volumes` entry to that bind path). The container runs as **UID 1000**; the host directory must be writable by that uid (typical fix: Ta5d6ff`sudo chown -R 1000:1000 ./meshchat-config`). If the directory is empty on first run, create it first so Docker does not create it as root-only.

**Inspect or reset the named volume**

Ta5d6ff```Ta5d6ffbash
docker volume inspect meshchatx-config
T8b949e# remove container and delete persisted data (destructive)
docker rm -f reticulum-meshchatx
docker volume rm meshchatx-config
Ta5d6ff```

Tc9d1d9## Install from Release Artifacts

Tc9d1d9### 1) Linux AppImage (x64/arm64)

Tff7b721. Download Ta5d6ff`ReticulumMeshChatX-v<version>-linux-<arch>.AppImage` from releases.
Tff7b722. Make it executable and run:

Ta5d6ff```Ta5d6ffbash
chmod +x ./ReticulumMeshChatX-v*-linux-*.AppImage
./ReticulumMeshChatX-v*-linux-*.AppImage
Ta5d6ff```

Tc9d1d9### 2) Debian/Ubuntu `.deb` (x64/arm64)

Tff7b721. Download Ta5d6ff`ReticulumMeshChatX-v<version>-linux-<arch>.deb`.
Tff7b722. Install:

Ta5d6ff```Ta5d6ffbash
sudo apt install ./ReticulumMeshChatX-v*-linux-*.deb
Ta5d6ff```

Tc9d1d9### 3) RPM-based systems

Tff7b721. Download Ta5d6ff`ReticulumMeshChatX-v<version>-linux-<arch>.rpm` if present in the release.
Tff7b722. Install with your distro tool:

Ta5d6ff```Ta5d6ffbash
sudo rpm -Uvh ./ReticulumMeshChatX-v*-linux-*.rpm
Ta5d6ff```

Tc9d1d9### 4) Python wheel (`.whl`)

Release wheels include the built web assets.

Ta5d6ff```Ta5d6ffbash
pip install ./reticulum_meshchatx-*-py3-none-any.whl
meshchatx --headless
Ta5d6ff```

Ta5d6ff`pipx` is also supported:

Ta5d6ff```Ta5d6ffbash
pipx install ./reticulum_meshchatx-*-py3-none-any.whl
Ta5d6ff```

Tc9d1d9## Run from Source (Web Server Mode)

Use this when developing or when you need a local custom build.

Ta5d6ff```Ta5d6ffbash
git clone https://github.com/Quad4-Software/MeshChatX.git
Tffa657cd MeshChatX
corepack Tffa657enable
pnpm config Tffa657set verify-store-integrity Tffa657true
pnpm install --frozen-lockfile
pip install Ta5d6ff"uv==0.11.15"
uv lock --check
uv sync --group dev
pnpm run build-frontend
uv run python -m meshchatx.meshchat --headless --host T79c0ff127.0.0.1
Ta5d6ff```

Notes on the install commands above:

Tff7b72- Ta5d6ff`pnpm install --frozen-lockfile` refuses to update Ta5d6ff`pnpm-lock.yaml` and fails if the lockfile does not match Ta5d6ff`package.json`. This is what blocks an unexpected upstream version from being silently pulled in.
Tff7b72- Ta5d6ff`verify-store-integrity=true` is also set in the project Ta5d6ff`pnpm-workspace.yaml`; the explicit Ta5d6ff`pnpm config set` line above just hardens the user-level config too.
Tff7b72- Lifecycle scripts (Ta5d6ff`preinstall`/Ta5d6ff`postinstall`) are blocked by default in pnpm v11+. Only the packages listed under Ta5d6ff`allowBuilds` in Ta5d6ff`pnpm-workspace.yaml` are allowed to run install scripts (currently Ta5d6ff`electron`, Ta5d6ff`electron-winstaller`, Ta5d6ff`esbuild`).
Tff7b72- Ta5d6ff`uv lock --check` fails fast if Ta5d6ff`uv.lock` is out of sync with Ta5d6ff`pyproject.toml`; Ta5d6ff`uv sync` then resolves only from the lockfile.
Tff7b72- For a strict lockfile-only UV install (no implicit lockfile refresh), pin UV with Ta5d6ff`pip install "uv==0.11.15"` to match what CI uses.

If you intentionally want to update dependencies, run Ta5d6ff`pnpm update` / Ta5d6ff`uv lock` in a dedicated commit and review the resulting lockfile diff before pushing.

Tc9d1d9## Run sandboxed (Linux)

To run the native Ta5d6ff`meshchatx` binary (alias: Ta5d6ff`meshchat`) with extra filesystem isolation, you can use **Firejail** or **Bubblewrap** (Ta5d6ff`bwrap`) while keeping normal network access for Reticulum and the web UI. Full examples (pip/pipx, Poetry, USB serial notes) are in:

Tff7b72- [Ta5d6ff`docs/en/platform-guides/linux-sandbox.md`](docs/en/platform-guides/linux-sandbox.md)

The same page appears in the in-app **Documentation** list (MeshChatX docs) when served from the bundled or synced Ta5d6ff`meshchatx-docs` files.

Tc9d1d9## Linux desktop: emoji fonts

The emoji picker renders standard Unicode emoji using your system fonts (Electron/Chromium). If emoji show as empty squares (“tofu”), install a color emoji package and restart the app.

| Family (examples) | Package |
| -------------------------- | -------------------------------------------------------------------- |
| Arch Linux, Artix, Manjaro | Ta5d6ff`noto-fonts-emoji` (Ta5d6ff`sudo pacman -S noto-fonts-emoji`) |
| Debian, Ubuntu | Ta5d6ff`fonts-noto-color-emoji` (Ta5d6ff`sudo apt install fonts-noto-color-emoji`) |
| Fedora | Ta5d6ff`google-noto-emoji-color-fonts` |

After installing, run Ta5d6ff`fc-cache -fv` if glyphs still fail until the next login. Optional: Ta5d6ff`noto-fonts` for broader symbol coverage on minimal installs.

Tc9d1d9## Windows desktop: microphone (Electron, Windows 10 / 11)

Calls and voice attachments use the microphone through Chromium inside the desktop app. If the UI shows no access or **getUserMedia** fails, check **Windows privacy** first (this is a frequent cause for “classic” Win32 apps, including Electron):

Tff7b721. Press **Win + R**, paste **`ms-settings:privacy-microphone`**, press Enter.
Tff7b722. Turn **Microphone access** on.
Tff7b723. Enable **Let desktop apps access your microphone** (wording may vary slightly by Windows version).
Tff7b724. Ensure MeshChatX is not denied under **Choose which apps can access your microphone** if that list appears.

Also confirm the app is not muted in **Settings → System → Sound** and that a working input device is selected.

Tc9d1d9## Offline Builds

MeshChatX supports two levels of offline building:

Tff7b721. **Cached offline builds**: you already ran Ta5d6ff`make install` once and have Ta5d6ff`node_modules/`, Ta5d6ff`.venv/`, and local caches.
Tff7b722. **Air-gapped (zero-network) builds**: the machine has _never_ had internet. You create an offline bundle on a networked machine and transfer it.

Tc9d1d9### Cached Offline Builds

Set Ta5d6ff`MESHCHATX_OFFLINE_BUILD=1` before running any build command. This skips all network fetches (micron-parser-go WASM, Reticulum manual, repository wheels) and runs package managers in offline mode. If a required cached asset is missing, the build fails with a clear error instead of hanging.

Ta5d6ff```Ta5d6ffbash
T8b949e# Install dependencies offline (requires populated pnpm store and uv cache)
Te6edf3MESHCHATX_OFFLINE_BUILDTff7b72=T79c0ff1 make install

T8b949e# Build frontend + backend offline
Te6edf3MESHCHATX_OFFLINE_BUILDTff7b72=T79c0ff1 pnpm run build:offline

T8b949e# Build Linux desktop packages offline
Te6edf3MESHCHATX_OFFLINE_BUILDTff7b72=T79c0ff1 pnpm run dist:linux:offline

T8b949e# Android Gradle also respects the flag
Te6edf3MESHCHATX_OFFLINE_BUILDTff7b72=T79c0ff1 ./gradlew :app:assembleRelease
Ta5d6ff```

Tff7b72> **Note:** Cached offline mode only skips _build-time_ network access. The first `make install` must be run online (or with pre-populated caches) so that `pnpm` and `uv` have the packages available locally.

Tc9d1d9### Air-Gapped Builds (No Cache)

For machines with no internet access at all, create an offline bundle on a networked machine and transfer it.

**On the online machine:**

Ta5d6ff```Ta5d6ffbash
T8b949e# Create the bundle (includes node_modules, Python wheels, and tooling caches)
pnpm run bundle:offline

T8b949e# Optional: also pre-download packaging tools (appimagetool, etc.)
bash scripts/create-offline-bundle.sh --warm-packaging

T8b949e# Transfer the bundle to your air-gapped machine
tar czf meshchatx-offline-linux-x64.tar.gz -C vendor/offline meshchatx-offline-bundle-*/
Ta5d6ff```

**On the air-gapped machine:**

Ta5d6ff```Ta5d6ffbash
T8b949e# Extract the bundle into the project
tar xzf meshchatx-offline-linux-x64.tar.gz

T8b949e# Install from the bundle (extracts node_modules and sets up caches)
bash scripts/install-offline.sh

T8b949e# Build completely offline
Te6edf3MESHCHATX_OFFLINE_BUILDTff7b72=T79c0ff1 make build

T8b949e# Or package offline
Te6edf3MESHCHATX_OFFLINE_BUILDTff7b72=T79c0ff1 pnpm run dist:linux
Ta5d6ff```

The bundle is platform-specific because it contains native binaries (Electron, esbuild, etc.). Create it on the same OS/architecture as the air-gapped build host.

Prerequisites on the air-gapped machine: Ta5d6ff`node`, Ta5d6ff`pnpm`, Ta5d6ff`uv`, and Ta5d6ff`python3` must be installed (the bundle provides all dependencies and caches, not the toolchain itself).

Tff7b72> **Android builds:** The offline bundle does **not** include Android Chaquopy wheels. Build those separately on an online machine (`bash scripts/build-android-wheels-local.sh`) and copy `android/vendor/` to the air-gapped host alongside the project. Then run Gradle with `MESHCHATX_OFFLINE_BUILD=1`.

Tc9d1d9## Build Desktop Packages from Source

These scripts are defined in Ta5d6ff`package.json` and Ta5d6ff`Taskfile.yml`.

Tc9d1d9### Linux x64 AppImage + DEB

Ta5d6ff```Ta5d6ffbash
pnpm run dist:linux-x64
Ta5d6ff```

Tc9d1d9### Linux arm64 AppImage + DEB

Ta5d6ff```Ta5d6ffbash
pnpm run dist:linux-arm64
Ta5d6ff```

Tc9d1d9### RPM

Ta5d6ff```Ta5d6ffbash
pnpm run dist:rpm
Ta5d6ff```

Or through Task:

Ta5d6ff```Ta5d6ffbash
task dist:fe:rpm
Ta5d6ff```

Tc9d1d9## Container build (wheel, AppImage, deb, rpm)

Ta5d6ff`Dockerfile.build` runs the same shell-driven steps CI uses (Poetry, pnpm, Ta5d6ff`task`, packaging APT deps). It is oriented toward **linux/amd64** (NodeSource amd64 tarball, Task amd64 binary). Default target is everything; override with a build arg.

Targets for Ta5d6ff`MESHCHATX_BUILD_TARGETS`: Ta5d6ff`all` (default), Ta5d6ff`wheel`, or Ta5d6ff`electron` (AppImage + deb for x64 and arm64, best-effort RPM, no wheel).

Build:

Ta5d6ff```Ta5d6ffbash
docker build -f Dockerfile.build -t meshchatx-build:local .
Ta5d6ff```

Build only a wheel:

Ta5d6ff```Ta5d6ffbash
docker build -f Dockerfile.build --build-arg Te6edf3MESHCHATX_BUILD_TARGETSTff7b72=wheel -t meshchatx-build:wheel .
Ta5d6ff```

Copy Ta5d6ff`/artifacts` from the finished image to the host:

Ta5d6ff```Ta5d6ffbash
Te6edf3cidTff7b72=Tff7b72$(docker create meshchatx-build:localTff7b72)
docker cp Ta5d6ff"Tffd700${Te6edf3cidTffd700}Ta5d6ff:/artifactsTa5d6ff" ./meshchatx-artifacts
docker rm Ta5d6ff"Tffd700${Te6edf3cidTffd700}Ta5d6ff"
Ta5d6ff```

Tc9d1d9## Architecture Support Summary

Tff7b72- Docker image: Ta5d6ff`amd64`, Ta5d6ff`arm64`
Tff7b72- Linux AppImage: Ta5d6ff`x64`, Ta5d6ff`arm64`
Tff7b72- Linux DEB: Ta5d6ff`x64`, Ta5d6ff`arm64`
Tff7b72- Windows: Ta5d6ff`x64`, Ta5d6ff`arm64` (build scripts available)
Tff7b72- macOS: build scripts available (Ta5d6ff`arm64`, Ta5d6ff`universal`) for local build environments
Tff7b72- Android: universal APK only (see [Ta5d6ff`android/README.md`](android/README.md))

Tc9d1d9## Android

MeshChatX supports native Android APK builds (not only Termux).

Tc9d1d9### Build APKs from source

From repo root:

Ta5d6ff```Ta5d6ffbash
T8b949e# 1) Build Chaquopy wheels used by android/app/build.gradle
bash scripts/build-android-wheels-local.sh

T8b949e# 2) Build universal APKs (one debug + one release per run; see android/README.md)
Tffa657cd android
./gradlew --no-daemon :app:assembleDebug :app:assembleRelease
Ta5d6ff```

Offline Android builds are supported by setting Ta5d6ff`MESHCHATX_OFFLINE_BUILD=1`:

Ta5d6ff```Ta5d6ffbash
Te6edf3MESHCHATX_OFFLINE_BUILDTff7b72=T79c0ff1 ./gradlew --no-daemon :app:assembleRelease
Ta5d6ff```

This skips the repository wheels fetch step. The Ta5d6ff`android/vendor/` wheels and Ta5d6ff`meshchatx/public/repository-server-bundled/bundled/` must already be present.

There is a **single** Android variant. Gradle syncs the full Ta5d6ff`meshchatx/` tree into Ta5d6ff`app/src/main/python/meshchatx/`, including the offline repository wheel bundle. Published and documented builds use **universal** packaging only: one debug APK and one release APK per run, each containing the native ABIs configured in Ta5d6ff`android/app/build.gradle`.

Tff7b72- Debug: Ta5d6ff`android/app/build/outputs/apk/debug/app-debug.apk`
Tff7b72- Release: Ta5d6ff`android/app/build/outputs/apk/release/app-release-unsigned.apk`

Notes:

Tff7b72- Release outputs are unsigned by default unless you configure signing (Ta5d6ff`scripts/sign-android-apks.sh`).
Tff7b72- Native ABIs embedded in the universal APK follow Ta5d6ff`android/app/build.gradle` (including Ta5d6ff`armeabi-v7a` when enabled). Building wheels for Ta5d6ff`armeabi-v7a` needs an Android SDK on Ta5d6ff`ANDROID_HOME` (see Ta5d6ff`android/README.md`).
Tff7b72- If repo root Ta5d6ff`dist/reticulum_meshchatx-*.whl` exists (for example from Ta5d6ff`python -m build --wheel -o dist .`), bundled repository refresh prefers that wheel over PyPI for the MeshChatX package. CI builds that wheel before the Android Gradle step.

Additional docs:

Tff7b72- [Ta5d6ff`docs/en/platform-guides/android-termux.md`](docs/en/platform-guides/android-termux.md)
Tff7b72- [Ta5d6ff`android/README.md`](android/README.md)

Tc9d1d9## Configuration

MeshChatX supports both CLI args and env vars.

| Argument | Environment Variable | Default | Description |
| -------------------------- | ---------------------------------------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Ta5d6ff`--host` | Ta5d6ff`MESHCHAT_HOST` | Ta5d6ff`127.0.0.1` | Web server bind address |
| Ta5d6ff`--port` | Ta5d6ff`MESHCHAT_PORT` | Ta5d6ff`8000` | Web server port |
| Ta5d6ff`--no-https` | Ta5d6ff`MESHCHAT_NO_HTTPS` | Ta5d6ff`false` | Disable HTTPS |
| Ta5d6ff`--ssl-cert` / Ta5d6ff`--ssl-key` | Ta5d6ff`MESHCHAT_SSL_CERT` / Ta5d6ff`MESHCHAT_SSL_KEY` | (none) | PEM certificate and private key paths; both must be set together. Overrides auto-generated certs under the identity Ta5d6ff`ssl/` directory. |
| Ta5d6ff`--rns-log-level` | Ta5d6ff`MESHCHAT_RNS_LOG_LEVEL` | (none) | Reticulum (RNS) stack log level: Ta5d6ff`none`, Ta5d6ff`critical`, Ta5d6ff`error`, Ta5d6ff`warning`, Ta5d6ff`notice`, Ta5d6ff`verbose`, Ta5d6ff`debug`, Ta5d6ff`extreme`, or a numeric level. CLI overrides env when both are set. |
| Ta5d6ff`--headless` | Ta5d6ff`MESHCHAT_HEADLESS` | Ta5d6ff`false` | Do not auto-launch browser |
| Ta5d6ff`--auth` | Ta5d6ff`MESHCHAT_AUTH` | Ta5d6ff`false` | Enable basic auth |
| Ta5d6ff`--reset-password` | Ta5d6ff`MESHCHAT_RESET_PASSWORD` | Ta5d6ff`false` | Clear the stored password hash so a new password can be set via the web UI |
| Ta5d6ff`--storage-dir` | Ta5d6ff`MESHCHAT_STORAGE_DIR` | Ta5d6ff`./storage` | Data directory |
| Ta5d6ff`--public-dir` | Ta5d6ff`MESHCHAT_PUBLIC_DIR` | auto/bundled | Frontend files directory (needed for source installs without bundled assets) |

Tc9d1d9## Branches

| Branch | Purpose |
| -------- | --------------------------------------------------------------- |
| Ta5d6ff`master` | Stable releases. Production-ready code only. |
| Ta5d6ff`dev` | Active development. May contain breaking or incomplete changes. |

Tc9d1d9## Development

Common tasks from Ta5d6ff`Taskfile.yml`:

Ta5d6ff```Ta5d6ffbash
task install
task format
task lint
task Tffa657test
task build
Ta5d6ff```

Ta5d6ff`Makefile` targets are thin shims that delegate to Ta5d6ff`task` (same commands as above):

| Command | Delegates to | Description |
| ---------------------- | -------------- | --------------------------------------------- |
| Ta5d6ff`make install` | Ta5d6ff`task install` | Install pnpm and UV dependencies |
| Ta5d6ff`make run` | Ta5d6ff`task run` | Run MeshChatX via UV |
| Ta5d6ff`make build` | Ta5d6ff`task build` | Build frontend and backend artifacts |
| Ta5d6ff`make format` | Ta5d6ff`task format` | Format frontend and backend code |
| Ta5d6ff`make lint` | Ta5d6ff`task lint` | ESLint, vue-tsc, knip, Ruff, and basedpyright |
| Ta5d6ff`make test` | Ta5d6ff`task test` | Run frontend and backend tests |
| Ta5d6ff`make clean` | Ta5d6ff`task clean` | Remove build artifacts and node_modules |
| Ta5d6ff`make tree-rsm-verify` | (shell) | Verify Ta5d6ff`meshchatx.rsm` signature and hashes |
| Ta5d6ff`make tree-rsm-sign` | (shell) | Sign tree inventory (requires Ta5d6ff`RNS_ID_PATH`) |
| Ta5d6ff`make hooks-install` | (shell) | Enable tracked pre-commit RSM resign hook |

Tc9d1d9## Versioning

Current version in this repo is Ta5d6ff`4.8.2`.

Tff7b72- **`package.json`** Ta5d6ff`version` is the only value you edit for a release bump.
Tff7b72- Run **`pnpm run version:sync`** (also run at the start of **`pnpm run build`**) to propagate that version into **`pyproject.toml`**, **`meshchatx/src/version.py`**, **`THIRD_PARTY_NOTICES.txt`** (product line), **README** / **lang/README.\*** “current version” lines, **`docs/en/platform-guides/raspberry-pi.md`** pipx example, and **`packaging/arch/PKGBUILD`** helpers.
Tff7b72- **`meshchatx.__version__`** is read from **`meshchatx/src/version.py`** without importing **`meshchatx.src`**, so a plain Ta5d6ff`import meshchatx` stays lightweight.
Tff7b72- **Changelog** entries stay manual when you cut a release.

Tc9d1d9## Troubleshooting: database corruption and full data reset

If MeshChatX fails to start with errors such as Ta5d6ff`database disk image is malformed`, Ta5d6ff`DatabaseError`, or corrupted ratchet data, the desktop crash screen now offers recovery actions:

Tff7b72- **Restore latest backup** from Ta5d6ff`database-backups/` or Ta5d6ff`snapshots/` inside your MeshChatX storage folder
Tff7b72- **Choose backup file** to restore a Ta5d6ff`.zip` you saved elsewhere
Tff7b72- **Try auto-repair** to relaunch with Ta5d6ff`--auto-recover` (SQLite checkpoint / integrity pass)
Tff7b72- **Emergency mode** to open the app without the database so you can export data from About when possible
Tff7b72- **Copy reset instructions** with the exact folders to delete for a clean reinstall

Tc9d1d9### Where MeshChatX stores data

| Platform | MeshChatX storage | Reticulum network stack |
| ---------------- | ---------------------------------------------- | ------------------------------------ |
| Linux / macOS | Ta5d6ff`~/.reticulum-meshchatx/` | Ta5d6ff`~/.reticulum/` |
| Windows | Ta5d6ff`%USERPROFILE%\.reticulum-meshchatx\` | Ta5d6ff`%USERPROFILE%\.reticulum\` |
| Windows portable | Ta5d6ff`<MeshChatX.exe folder>\.reticulum-meshchatx\` | Ta5d6ff`<MeshChatX.exe folder>\.reticulum\` |

Legacy Reticulum MeshChat data may still exist at Ta5d6ff`~/.reticulum-meshchat/` (or the Windows equivalent).

Automatic database backups are written to:

Ta5d6ff`database-backups/` inside the MeshChatX storage folder when the app has run successfully before.

Tc9d1d9### Complete removal (start fresh)

Quit MeshChatX completely. On Windows, also end Ta5d6ff`ReticulumMeshChatX.exe` in Task Manager if it is still running. Then delete the MeshChatX storage folder and the Reticulum config folder for your install type (see table above). This removes your local identity, messages, contacts, path cache, and ratchet state. The next launch creates a new identity unless you restore from a backup first.

**Linux / macOS example:**

Ta5d6ff```Ta5d6ffbash
rm -rf ~/.reticulum-meshchatx ~/.reticulum ~/.reticulum-meshchat
Ta5d6ff```

**Windows (PowerShell) example:**

Ta5d6ff```Ta5d6ffpowershell
Tffa657Remove-Item Te6edf3-Recurse Te6edf3-Force Ta5d6ff"Ta5d6ff$Ta5d6ffenv:USERPROFILE\.reticulum-meshchatxTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff$Ta5d6ffenv:USERPROFILE\.reticulumTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff$Ta5d6ffenv:USERPROFILE\.reticulum-meshchatTa5d6ff" Te6edf3-ErrorAction Te6edf3SilentlyContinue
Ta5d6ff```

Custom installs: if you pass Ta5d6ff`--storage-dir` or Ta5d6ff`--reticulum-config-dir`, remove those directories instead of the defaults.

Tc9d1d9### Command-line restore (advanced)

When the backend can start briefly or you run from source:

Ta5d6ff```Ta5d6ffbash
meshchatx --storage-dir /path/to/storage --restore-db /path/to/backup.zip
Ta5d6ff```

Tc9d1d9## Security

Security and integrity details:

Tff7b72- [Ta5d6ff`SECURITY.md`](SECURITY.md)
Tff7b72- [Ta5d6ff`LEGAL.md`](LEGAL.md)
Tff7b72- Built-in integrity checks and HTTPS/WSS defaults in app runtime.
Tff7b72- CI and release builds on GitHub Actions.

Tc9d1d9## Adding a Language

My workflow: ArgosTranslate -> Local LLM (Qwen 3 + Gemma 4)

People are then welcome to submit fixes to me via LXMF (Ta5d6ff`f489752fbef161c64d65e385a4e9fc74`) or wherever you can contact me.

Locale discovery is automatic. Add a new file under Ta5d6ff`meshchatx/src/frontend/locales/` (for example Ta5d6ff`xx.json`) with the same keys as Ta5d6ff`en.json` and a top-level Ta5d6ff`_languageName` string for the label shown in the language selector. You can copy Ta5d6ff`en.json` and translate every value by hand; **machine-assisted generation is optional** and never required.

**Optional: Argos Translate bootstrap.** For a machine-generated first draft from Ta5d6ff`en.json`, use Ta5d6ff`scripts/argos_translate.py`. It handles formatting, color output, and protects interpolation variables (like Ta5d6ff`{count}`) from accidental edits.

Ta5d6ff```Ta5d6ffbash
T8b949e# Install argostranslate if you haven't already
pipx install argostranslate

T8b949e# Run the translation script
python scripts/argos_translate.py --from en --to xx --input meshchatx/src/frontend/locales/en.json --output meshchatx/src/frontend/locales/xx.json --name Ta5d6ff"Your Language Name"
Ta5d6ff```

After any machine-assisted pass, have an LLM or a human reviewer verify grammar, context, and tone (for example formal vs informal).

Run Ta5d6ff`pnpm test -- tests/frontend/i18n.test.js --run` to verify key parity with Ta5d6ff`en.json`.

No other code changes are required. The app, language selector, and tests all discover locales from the Ta5d6ff`meshchatx/src/frontend/locales/` directory at build time.

Tc9d1d9## Donation

Donations are voluntary. They help fund time and effort to develop this app.

**Ways to give:** [Ta5d6ff`donate.md`](donate.md) (Monero, Ko-Fi, Buy Me a Coffee).

Tc9d1d9## Credits

Tff7b72- [Tff7b72Liam Cottle](Te6edf3https://github.com/liamcottle) - Original Reticulum MeshChat
Tff7b72- [Tff7b72RFnexus](Te6edf3https://github.com/RFnexus) - micron parser JavaScript work
Tff7b72- [Tff7b72markqvist](Te6edf3https://github.com/markqvist) - Reticulum, LXMF, LXST

Tc9d1d9## License

Project-owned portions are licensed under 0BSD.
Original upstream portions from Reticulum MeshChat remain under MIT.
See [Ta5d6ff`LICENSE`](LICENSE) for full text and notices.


──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────